#include "qs_misc.h"
#include "qs_config.h"
#include "main.h"
#include "qs_sched.h"
#include "qs_action.h"
#include "qs_pwm.h"

#define soureless_buzzer

static uint8_t beep_freq = 0;
static uint8_t beep_timeout_timer = 0;
static uint8_t beep_cycle = 0;
static void qs_buzz_on(void);
static void qs_buzz_off(void);

static void qs_led_pin_init(void)
{
    LL_GPIO_SetPinMode(QS_LED_PORT,QS_LED_PIN,LL_GPIO_MODE_OUTPUT);
    LL_GPIO_SetPinOutputType(QS_LED_PORT,QS_LED_PIN,LL_GPIO_OUTPUT_PUSHPULL);
	  LL_GPIO_SetOutputPin(QS_LED_PORT,QS_LED_PIN);
}

static void on_misc_20ms_handle(void)
{
	  static uint8_t prescale_500ms = 25;
	  
	  prescale_500ms --;
	  if(prescale_500ms == 0 && m_provison_timeout > 0){
		  prescale_500ms = 25;
			LL_GPIO_TogglePin(QS_LED_PORT,QS_LED_PIN);
		} 
		
		
    if(beep_cycle>0){
		  beep_cycle --;
		  beep_freq = (beep_cycle>0) ? beep_freq:beep_freq-1;
	    if(beep_timeout_timer > 0){
	      qs_buzz_on();
			  beep_timeout_timer --;
		  }else 
		     qs_buzz_off();
	  }else {
	    if(beep_freq > 0) {
		    beep_timeout_timer = IN_BEEP_TIME;
			  beep_cycle = 2 * beep_timeout_timer;
		  }	
			qs_buzz_off();
	  }			  
}


void qs_led_set(bool avtive)
{
    if(avtive) 
			LL_GPIO_ResetOutputPin(QS_LED_PORT,QS_LED_PIN);
		else
			LL_GPIO_SetOutputPin(QS_BEEP_CTRL_PORT,QS_BEEP_CTRL_PIN);
}

#ifdef soureless_buzzer
static void qs_buzz_pin_init(void)
{
     LL_RCC_LSI_Enable();
     while(LL_RCC_LSI_IsReady() != 1)
    {
    }
 
   /* Configure PA01 as alternate function and set it as MCO output pin */
    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    /* Select pin 1 */
    GPIO_InitStruct.Pin = QS_BEEP_CTRL_PIN; 
    /* Set mode as alternate function */
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; 
    /* Select alternate function 5 (AF15) */
    GPIO_InitStruct.Alternate = LL_GPIO_AF_15;     
    /* Set output speed as very high frequency */
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;   
    /* Set output type as push-pull */
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    /* Set no pull-up/pull-down */
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;                
  
    /* Initialize GPIOA */
    LL_GPIO_Init(QS_BEEP_CTRL_PORT,&GPIO_InitStruct);

//		/*MCO (Microcontroller Clock Output) clock and divider initialization */
//    LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_LSI,LL_RCC_MCO1_DIV_32);
}
void qs_buzz_on(void)
{
/* Configure PA01 as alternate function and set it as MCO output pin */
    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    /* Select pin 1 */
    GPIO_InitStruct.Pin = QS_BEEP_CTRL_PIN; 
    /* Set mode as alternate function */
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; 
    /* Select alternate function 5 (AF15) */
    GPIO_InitStruct.Alternate = LL_GPIO_AF_15;     
    /* Set output speed as very high frequency */
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;   
    /* Set output type as push-pull */
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    /* Set no pull-up/pull-down */
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;                
  
    /* Initialize GPIOA */
    LL_GPIO_Init(QS_BEEP_CTRL_PORT,&GPIO_InitStruct);
		/*MCO (Microcontroller Clock Output) clock and divider initialization */
    LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_LSI,LL_RCC_MCO1_DIV_32);


}

void qs_buzz_off(void)
{

    HAL_GPIO_DeInit(QS_BEEP_CTRL_PORT ,QS_BEEP_CTRL_PIN);

}

#else
static void qs_buzz_pin_init(void)
{
    LL_GPIO_SetPinMode(QS_BEEP_CTRL_PORT,QS_BEEP_CTRL_PIN,LL_GPIO_MODE_OUTPUT);
    LL_GPIO_SetPinOutputType(QS_BEEP_CTRL_PORT,QS_BEEP_CTRL_PIN,LL_GPIO_OUTPUT_PUSHPULL);
	  LL_GPIO_ResetOutputPin(QS_BEEP_CTRL_PORT,QS_BEEP_CTRL_PIN);
}

void qs_buzz_on(void)
{
     LL_GPIO_SetOutputPin(QS_BEEP_CTRL_PORT,QS_BEEP_CTRL_PIN);

}

void qs_buzz_off(void)
{
    LL_GPIO_ResetOutputPin(QS_BEEP_CTRL_PORT,QS_BEEP_CTRL_PIN);

}

#endif

void qs_misc_init(void)
{
  
    qs_buzz_pin_init();
	  qs_led_pin_init();
    qs_on_misc_20ms_handle_set(on_misc_20ms_handle);

}

void qs_buzz_set(uint8_t freq)
{
    if(freq > 0){
		  beep_freq = freq;
			beep_timeout_timer = IN_BEEP_TIME;
			beep_cycle = 2 * beep_timeout_timer;
		}

}

